КОС.отд
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы
 
 glagol.png Программируем по-русски
 

Основная задача Глагола — дать человеку возможность воплощать свои мысли на языке, близком к его родному языку.

Издатель Глагола
 

 
(*~\Глагол\Отделы\Обмен~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                        ОТДЕЛ КОС;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: взаимодействие с Консольной Оконной Системой
 *============================================================================*)
ИСПОЛЬЗУЕТ 
  ОБХОД,
  ЦвЗнак,
  ОС,
  Ввод;
ВИД
               (* посылки от ОС Win32 *)
  ОтКлавиш=НАБОР
    вид       :ОБХОД.Цел16;
    прозапас  :ОБХОД.Цел16;
    нажато-   :ЦЕЛ;
    повтор-   :ОБХОД.Цел16;
    код-      :ОБХОД.Цел16;
    мкод-     :ОБХОД.Цел16;
    знак-     :ЗНАК;
    упрКнопки-:МНОЖ;
  КОН;
  ОтМышки=НАБОР
    вид       :ОБХОД.Цел16;
    прозапас  :ОБХОД.Цел16;
    к-        :ОБХОД.Цел16;
    с-        :ОБХОД.Цел16;
    кнопки-   :МНОЖ;
    упрКнопки-:МНОЖ;
    события-  :МНОЖ;
  КОН;
  TIMERPROC=ЗАДАЧА*(uID,uMsg,dwUser,dw1,dw2:ЦЕЛ);
               (* прямоугольная область экрана *)
  Область=НАБОР
    лк:ОБХОД.Цел16; (* левая колонка  *) 
    вс:ОБХОД.Цел16; (* верхняя строка *) 
    пк:ОБХОД.Цел16; (* правая колонка *) 
    нс:ОБХОД.Цел16; (* нижняя строка  *)
  КОН;
               (* состояние указки *)
  СостояниеУказки=НАБОР
    размер,видимость:ЦЕЛ
  КОН;

(******************************************************************************
 * Задача выполняющаяся по времени
 ******************************************************************************)
ВИД  
  ВидЗадачиЧасы-=ЗАДАЧА(номер:ЦЕЛ);
ПЕР
  ЗадачаЧасы:ВидЗадачиЧасы;

             (* используемые Win задачи *)
ЗАДАЧА SetConsoleMode(
 hConsoleHandle,
 dwMode:ЦЕЛ);                  ВЫЗОВ "SetConsoleMode"                ИЗ "kernel32.dll";

ЗАДАЧА GetNumberOfConsoleInputEvents(
 hConsoleInput,
 lpNumberOfEvents+:ЦЕЛ);       ВЫЗОВ "GetNumberOfConsoleInputEvents" ИЗ "kernel32.dll";

ЗАДАЧА ReadConsoleInput(
 hConsoleInput:ЦЕЛ;
 lpBuffer+:ОтМышки;
 nLength,
 lpNumberOfEventsRead+:ЦЕЛ);   ВЫЗОВ "ReadConsoleInputW"             ИЗ "kernel32.dll";

ЗАДАЧА WaitForSingleObject(
 hHandle,
 dwMilliseconds:ЦЕЛ);          ВЫЗОВ "WaitForSingleObject"           ИЗ "kernel32.dll";

ЗАДАЧА ReadConsoleOutputCharacter(
 hConsoleOutput:ЦЕЛ;
 lpCharacter+:ЗНАК;
 nLength,
 dwReadCoord,
 lpNumberOfCharsRead+:ЦЕЛ);    ВЫЗОВ "ReadConsoleOutputCharacterW"   ИЗ "kernel32.dll";

ЗАДАЧА WriteConsoleOutputCharacter(
 hConsoleOutput:ЦЕЛ;
 lpCharacter+:ЗНАК;
 nLength,
 dwWriteCoord,
 lpNumberOfCharsWritten+:ЦЕЛ); ВЫЗОВ "WriteConsoleOutputCharacterW"  ИЗ "kernel32.dll";

ЗАДАЧА ReadConsoleOutputAttribute(
 hConsoleOutput:ЦЕЛ;
 lpAttribute+:ЗНАК;
 nLength,
 dwReadCoord,
 lpNumberOfAttrsRead+:ЦЕЛ);    ВЫЗОВ "ReadConsoleOutputAttribute"    ИЗ "kernel32.dll";

ЗАДАЧА WriteConsoleOutputAttribute(
 hConsoleOutput:ЦЕЛ;
 lpAttribute+:ЗНАК;
 nLength,
 dwWriteCoord,
 lpNumberOfAttrsWritten+:ЦЕЛ); ВЫЗОВ "WriteConsoleOutputAttribute"   ИЗ "kernel32.dll";

ЗАДАЧА WriteConsoleOutput(
 hConsoleOutput:ЦЕЛ;
 lpBuffer-:ЦвЗнак.Строка;
 dwBufferSize,
 dwBufferCoord:ЦЕЛ;
 lpWriteRegion-:Область);      ВЫЗОВ "WriteConsoleOutputW"           ИЗ "kernel32.dll";

ЗАДАЧА SetConsoleCursorPosition(
 hConsoleOutput,
 dwCursorPosition:ЦЕЛ);        ВЫЗОВ "SetConsoleCursorPosition"      ИЗ "kernel32.dll";

ЗАДАЧА SetConsoleCursorInfo(hConsoleOutput:ЦЕЛ;
 lpConsoleCursorInfo+:СостояниеУказки); ВЫЗОВ "SetConsoleCursorInfo" ИЗ "kernel32.dll";

ЗАДАЧА ScrollConsoleScreenBuffer(
 hConsoleOutput:ЦЕЛ;
 lpScrollRectangle+,
 lpClipRectangle+:Область;
 dwDestinationOrigin:ЦЕЛ;
 lpFill-:ЦвЗнак.Вид);          ВЫЗОВ "ScrollConsoleScreenBufferW"    ИЗ "kernel32.dll";

ЗАДАЧА GetLargestConsoleWindowSize(
 hConsoleOutput:ЦЕЛ):ЦЕЛ;      ВЫЗОВ "GetLargestConsoleWindowSize"   ИЗ "kernel32.dll";

ЗАДАЧА SetConsoleScreenBufferSize(
 hConsoleOutput,dwSize:ЦЕЛ);   ВЫЗОВ "SetConsoleScreenBufferSize"    ИЗ "kernel32.dll";

ЗАДАЧА SetConsoleWindowInfo(
 hConsoleOutput,
 bAbsolute:ЦЕЛ;
 lpConsoleWindow-:Область);    ВЫЗОВ "SetConsoleWindowInfo"          ИЗ "kernel32.dll";

ЗАДАЧА timeSetEvent(
 uDelay,
 uResolution:ЦЕЛ;
 lpTimerProc:TIMERPROC;
 dwUser,
 fuEvent:ЦЕЛ):ЦЕЛ;             ВЫЗОВ "timeSetEvent"                  ИЗ "winmm.dll";

ЗАДАЧА timeKillEvent(uTimerID:ЦЕЛ); ВЫЗОВ "timeKillEvent"             ИЗ "winmm.dll";


(******************************************************************************)
ЗАДАЧА* Часы(uID,uMsg,dwUser,dw1,dw2:ЦЕЛ);
УКАЗ
  ЕСЛИ ЗадачаЧасы # ПУСТО ТО
    ЗадачаЧасы(dwUser)
  КОН
КОН Часы;

(******************************************************************************)
ЗАДАЧА Подготовить-(задачаЧасы:ВидЗадачиЧасы);
УКАЗ
  ЗадачаЧасы:=задачаЧасы
КОН Подготовить;

(******************************************************************************)
ЗАДАЧА Отработать-;
(* заглушка для совместимости с ГОС *)
УКАЗ
КОН Отработать;

(******************************************************************************)
ЗАДАЧА ПоказатьОкно-;
(* заглушка для совместимости с ГОС *)
УКАЗ
КОН ПоказатьОкно;

(******************************************************************************)
ЗАДАЧА СоздатьЧасы-(номер,время:ЦЕЛ):ЦЕЛ;
(* Цель: добавляет новые, или заменяет старые часы
 * До:   <номер> - опознавательный номер часов
 *       <время> - время повторения срабатывания данных часов в мс *)
УКАЗ
  ВОЗВРАТ timeSetEvent(время,время,Часы,номер,1)
КОН СоздатьЧасы;

(******************************************************************************)
ЗАДАЧА УдалитьЧасы-(часы:ЦЕЛ);
УКАЗ
  timeKillEvent(часы)
КОН УдалитьЧасы;

(******************************************************************************)
ЗАДАЧА РазмерЭкрана-(строк+,колонок+:ЦЕЛ);
(* Цель:  возвращает размер экрана *)
ПЕР
  ск:ЦЕЛ;
УКАЗ
  ск:=GetLargestConsoleWindowSize(ОС.ссылкаНаВывод);
  строк:=ск ДЕЛИТЬ 10000H;
  колонок:=ск ОСТАТОК 10000H
КОН РазмерЭкрана; 

(******************************************************************************)
ЗАДАЧА ИзменитьРазмерОкна-(строк,колонок:ЦЕЛ);
(* Цель:  изменить размер окна приложения *)
ПЕР
  область:Область;
  ск:ЦЕЛ;
УКАЗ
  (* подготовим рабочую область для увеличения окна *)
  ск:=строк*10000H+колонок;
  SetConsoleScreenBufferSize(ОС.ссылкаНаВывод,ск);
  (* изменение видимой области *)
  область.вс:=0;
  область.нс:=УЗК(строк-1);
  область.лк:=0;
  область.пк:=УЗК(колонок-1);
  SetConsoleWindowInfo(ОС.ссылкаНаВывод,1,область);
  (* поправим рабочую область при уменьшении окна *)
  SetConsoleScreenBufferSize(ОС.ссылкаНаВывод,ск)
КОН ИзменитьРазмерОкна; 

(******************************************************************************)
ЗАДАЧА Опрос-(отКлавиш+:Ввод.ОтКлавиш; отМышки+:Ввод.ОтМышки):ЦЕЛ;
ПЕР
  откуда,посылок:ЦЕЛ;
  ОСотМышки:ОтМышки;
  ОСотКлавиш:ОтКлавиш;
УКАЗ
  WaitForSingleObject(ОС.ссылкаНаВвод,-1);
  GetNumberOfConsoleInputEvents(ОС.ссылкаНаВвод,посылок);
  (* наверное, это посылка от мышки *)
  ReadConsoleInput(ОС.ссылкаНаВвод,ОСотМышки,1,посылок);
  откуда:=ОСотМышки.вид;
  ЕСЛИ откуда = Ввод.клавиши ТО  (* нет, не от мышки *)
    ОБХОД.Образ(ОБХОД.ПолучитьАдрес(ОСотМышки),ОБХОД.ПолучитьАдрес(ОСотКлавиш),20);
    (* ждём отпускания клавиши *)
    ЕСЛИ ОСотКлавиш.нажато = 0 ТО
      ВОЗВРАТ Ввод.пустой
    КОН;
    ЕСЛИ  (ОСотКлавиш.код = 10H)    (* просто шифт  *)
      ИЛИ (ОСотКлавиш.код = 11H)    (* просто контр *)
      ИЛИ (ОСотКлавиш.код = 12H) ТО (* просто альт  *)
      ВОЗВРАТ Ввод.пустой
    КОН;
    отКлавиш.код:=ОСотКлавиш.код;
    отКлавиш.мкод:=ОСотКлавиш.мкод;
    отКлавиш.знак:=ОСотКлавиш.знак;
    отКлавиш.упрКнопки:=ОСотКлавиш.упрКнопки;
    отКлавиш.упрШифт:=Ввод.шифт В ОСотКлавиш.упрКнопки;
    отКлавиш.упрКонтр:={Ввод.лКонтр,Ввод.пКонтр}*ОСотКлавиш.упрКнопки # {};
    отКлавиш.упрАльт:={Ввод.лАльт,Ввод.пАльт}*ОСотКлавиш.упрКнопки # {}
  АЕСЛИ  откуда = Ввод.мышка ТО
    ЕСЛИ Ввод.смещение В ОСотМышки.события ТО
      ВОЗВРАТ Ввод.пустой
    КОН;
    отМышки.к:=ОСотМышки.к;
    отМышки.с:=ОСотМышки.с;
    отМышки.кнопки:=ОСотМышки.кнопки;
    отМышки.упрКнопки:=ОСотМышки.упрКнопки;
    отМышки.события:=ОСотМышки.события;
    ЕСЛИ Ввод.прокрут В ОСотМышки.события ТО
      отМышки.прокрут:=ОБХОД.Значение(ЦЕЛ,отМышки.кнопки) ДЕЛИТЬ (10000H*120)
    ИНАЧЕ
      отМышки.прокрут:=0
    КОН;
    отМышки.отработана:=ОТКЛ
  ИНАЧЕ
    откуда:=Ввод.пустой
  КОН;
  ВОЗВРАТ откуда
КОН Опрос;

(******************************************************************************)
ЗАДАЧА ПереместитьУказку-,к:ЦЕЛ);
УКАЗ
  SetConsoleCursorPosition(ОС.ссылкаНаВывод,с*10000H+к)
КОН ПереместитьУказку;

(******************************************************************************)
ЗАДАЧА РазмерУказки-(размер:ЦЕЛ);
(* <размер> указывается в процентах,
 * при <размер> = 0 указка убирается с экрана *)
ПЕР
  состояние:СостояниеУказки;
УКАЗ
  ЕСЛИ размер = 0 ТО
    состояние.видимость:=0;
    состояние.размер:=1
  ИНАЧЕ
    состояние.видимость:=1;
    состояние.размер:=размер
  КОН;
  SetConsoleCursorInfo(ОС.ссылкаНаВывод,состояние)
КОН РазмерУказки;

(******************************************************************************)
ЗАДАЧА ПисатьЗнак-,к:ЦЕЛ; зн:ЗНАК);
ПЕР
  отработано:ЦЕЛ;
УКАЗ
  WriteConsoleOutputCharacter(ОС.ссылкаНаВывод,зн,1,с*10000H+к,отработано)
КОН ПисатьЗнак;

(******************************************************************************)
ЗАДАЧА ЧитатьЗнак-,к:ЦЕЛ):ЗНАК;
ПЕР
  отработано:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  ReadConsoleOutputCharacter(ОС.ссылкаНаВывод,зн,1,с*10000H+к,отработано);
  ВОЗВРАТ зн
КОН ЧитатьЗнак;

(******************************************************************************)
ЗАДАЧА ПисатьЦвет-,к:ЦЕЛ; цв:ЗНАК);
ПЕР
  отработано:ЦЕЛ;
УКАЗ
  WriteConsoleOutputAttribute(ОС.ссылкаНаВывод,цв,1,с*10000H+к,отработано);
КОН ПисатьЦвет;

(******************************************************************************)
ЗАДАЧА ЧитатьЦвет-,к:ЦЕЛ):ЗНАК;
ПЕР
  отработано:ЦЕЛ;
  цв:ЗНАК;
УКАЗ
  ReadConsoleOutputAttribute(ОС.ссылкаНаВывод,цв,1,с*10000H+к,отработано);
  ВОЗВРАТ цв
КОН ЧитатьЦвет;

(******************************************************************************)
ЗАДАЧА Вверх-(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
(* Цель:  сдвиг содержимого заданной области вверх
 * До:    <вс>,<лк>,<нс>,<пк> - границы области на окне
 *        <новЗнак>           - знак для заполнения освободившегося места *)
ПЕР
  область:Область;
УКАЗ
  область.лк:=УЗК(лк);
  область.вс:=УЗК(вс);
  область.пк:=УЗК(пк);
  область.нс:=УЗК(нс);
  ScrollConsoleScreenBuffer(ОС.ссылкаНаВывод,область,область,(вс-1)*10000H+лк,новЗнак)
КОН Вверх;

(******************************************************************************)
ЗАДАЧА Вниз-(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
(* Цель:  сдвиг содержимого данной области вниз
 * До:    <вс>,<лк>,<нс>,<пк> - границы области на окне
 *        <новЗнак>           - знак для заполнения освободившегося места *)
ПЕР
  область:Область;
УКАЗ
  область.лк:=УЗК(лк);
  область.вс:=УЗК(вс);
  область.пк:=УЗК(пк);
  область.нс:=УЗК(нс);
  ScrollConsoleScreenBuffer(ОС.ссылкаНаВывод,область,область,(вс+1)*10000H+лк,новЗнак)
КОН Вниз;

(******************************************************************************)
ЗАДАЧА ПисатьСтроку-(цвСтрока-:ЦвЗнак.Строка; с,к,длина:ЦЕЛ);
(* Цель:  отрисовка содержимого строки 
 * До:    <с>,<к> - начало строки на экране
 *        <длина> - длина строки *)
(******************************************************************************)
ПЕР
  область:Область;
УКАЗ
  область.лк:=УЗК(к);
  область.вс:=УЗК(с);
  область.пк:=УЗК(к+длина-1);
  область.нс:=УЗК(с);
  WriteConsoleOutput(ОС.ссылкаНаВывод,цвСтрока,1*10000H+РАЗМЕР(цвСтрока),0,область)
КОН ПисатьСтроку;

(******************************************************************************)
УКАЗ
  (* подключаем мышку *)
  SetConsoleMode(ОС.ссылкаНаВвод,10H)
КОН КОС.

 
 


Вопросы, замечания и предложения высылайте на atimopheyev@yahoo.com

 
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы